///PHILOTES Source Code.  (C)2012 PhiloLabs
#pragma once

#include "ExtrasPrerequisites.h "

#include "OgrePrerequisites.h"
#include "OverlayElement.h"
#include "OgreIteratorWrappers.h"


namespace Extras {

	
    class _PhiloExtrasExport OverlayContainer : public OverlayElement
    {
    public:
        typedef map<Ogre::String, OverlayElement*>::type ChildMap;
        typedef MapIterator<ChildMap> ChildIterator;
        typedef map<Ogre::String, OverlayContainer*>::type ChildContainerMap;
        typedef MapIterator<ChildContainerMap> ChildContainerIterator;
    protected:
        // Map of all children
        ChildMap mChildren;
        // Map of container children (subset of mChildren)
        ChildContainerMap mChildContainers;

		bool mChildrenProcessEvents;
 
    public:
        /// Constructor: do not call direct, use OverlayManager::createOverlayElement
        OverlayContainer(const Ogre::String& name);
        virtual ~OverlayContainer();

        
        virtual void addChild(OverlayElement* elem);
        
        virtual void addChildImpl(OverlayElement* elem);
        
        virtual void addChildImpl(OverlayContainer* cont);
        
        virtual void removeChild(const Ogre::String& name);
        
        virtual OverlayElement* getChild(const Ogre::String& name);

		
		void initialise(void);

        void _addChild(OverlayElement* elem);
        void _removeChild(OverlayElement* elem) { _removeChild(elem->getName()); }
        void _removeChild(const Ogre::String& name);

        
        virtual ChildIterator getChildIterator(void);

        
        virtual ChildContainerIterator getChildContainerIterator(void);

		
		virtual void _positionsOutOfDate(void);

        
        virtual void _update(void);

        
        virtual ushort _notifyZOrder(ushort newZOrder);

        
        virtual void _notifyViewport();

        
        virtual void _notifyWorldTransforms(const Matrix4& xform);

        
	    virtual void _notifyParent(OverlayContainer* parent, Overlay* overlay);

        
        virtual void _updateRenderQueue(RenderQueue* queue);

        
		inline bool isContainer() const
		{ return true; }

		
		virtual inline bool isChildrenProcessEvents() const
		{ return true; }

		
		virtual inline void setChildrenProcessEvents(bool val)
		{ mChildrenProcessEvents = val; }

        
		virtual OverlayElement* findElementAt(Real x, Real y);		// relative to parent

	    void copyFromTemplate(OverlayElement* templateOverlay);
        virtual OverlayElement* clone(const Ogre::String& instanceName);

    };


}


